package com.cn.pojo;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.junit.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component ///通知类必须配置成Spring管理的bean
@Aspect //设置当前类为切面类类
public class MyAdvice {

    //设置切入点，@Pointcut注解要求配置在方法上方
    @Pointcut("execution(void com.cn.pojo.BookDao.update())")
    private void pt(){}

    @Pointcut("execution(void com..BookDao.throwException())")
    private void pt1(){}

    @Pointcut("execution(int com.cn.pojo.BookDao.addNumbers(..))")
    private void pt2(){}


    //设置在切入点pt()的前面运行当前操作(Before通知)
    //8.2.1 前置通知: 在切入点方法执行之前执行 @Before("切入点方法名()")
    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }

    @After("pt()")
    public void after(){
        System.out.println("after方法后执行");
    }


    @AfterReturning("pt()")
    public void afterReturnMethod(){
        System.out.println("方法正常执行后执行");
    }

    @AfterThrowing("pt1()")
    public void afterThrowing(){
    }

    @Around("pt2()")
    //1. 环绕通知方法形参必须是ProceedingJoinPoint，表示正在执行的连接点，使用该对象的 proceed()方法表示对原始对象方法进行调用，返回值为原始对象方法的返回值。
    //2. 环绕通知方法的返回值建议写成Object类型，用于将原始对象方法的返回值进行返回，哪 里使用代理对象就返回到哪里。
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around before advice..");
        Object proceed = joinPoint.proceed();
        System.out.println("计算的结果是:"+proceed);
        System.out.println("around after advice..");
        return proceed;
    }

}
